1include <BOSL/constants.scad>
2use <BOSL/transforms.scad>
3use <BOSL/beziers.scad>
4use <BOSL/math.scad>
5
6
7function CR_corner(size, orient=[0,0,0], trans=[0,0,0]) =
8 let (
9 r = 0.4,
10 k = r/2,
11 // I know this patch is not yet correct for continuous
12 // rounding, but it's a first approximation proof of concept.
13 // Currently this is a degree 4 triangular patch.
14 patch = [
15 [[0,1,1], [0,r,1], [0,0,1], [r,0,1], [1,0,1]],
16 [[0,1,r], [0,k,k], [k,0,k], [1,0,r]],
17 [[0,1,0], [k,k,0], [1,0,0]],
18 [[r,1,0], [1,r,0]],
19 [[1,1,0]]
20 ]
21 ) [for (row=patch)
22 translate_points(v=trans,
23 rotate_points3d(v=orient,
24 scale_points(v=size, row)
25 )
26 )
27 ];
28
29
30function CR_edge(size, orient=[0,0,0], trans=[0,0,0]) =
31 let (
32 r = 0.4,
33 a = -1/2,
34 b = -1/4,
35 c = 1/4,
36 d = 1/2,
37 // I know this patch is not yet correct for continuous
38 // rounding, but it's a first approximation proof of concept.
39 // Currently this is a degree 4 rectangular patch.
40 patch = [
41 [[1,0,a], [1,0,b], [1,0,0], [1,0,c], [1,0,d]],
42 [[r,0,a], [r,0,b], [r,0,0], [r,0,c], [r,0,d]],
43 [[0,0,a], [0,0,b], [0,0,0], [0,0,c], [0,0,d]],
44 [[0,r,a], [0,r,b], [0,r,0], [0,r,c], [0,r,d]],
45 [[0,1,a], [0,1,b], [0,1,0], [0,1,c], [0,1,d]]
46 ]
47 ) [for (row=patch)
48 translate_points(v=trans,
49 rotate_points3d(v=orient,
50 scale_points(v=size, row)
51 )
52 )
53 ];
54
55
56module CR_cube(size=[100,100,100], r=10, splinesteps=8, cheat=false)
57{
58 s = size-2*[r,r,r];
59 h = size/2;
60 corners = [
61 CR_corner([r,r,r], orient=ORIENT_Z, trans=[-size.x/2, -size.y/2, -size.z/2]),
62 CR_corner([r,r,r], orient=ORIENT_Z_90, trans=[ size.x/2, -size.y/2, -size.z/2]),
63 CR_corner([r,r,r], orient=ORIENT_Z_180, trans=[ size.x/2, size.y/2, -size.z/2]),
64 CR_corner([r,r,r], orient=ORIENT_Z_270, trans=[-size.x/2, size.y/2, -size.z/2]),
65
66 CR_corner([r,r,r], orient=ORIENT_ZNEG, trans=[ size.x/2, -size.y/2, size.z/2]),
67 CR_corner([r,r,r], orient=ORIENT_ZNEG_90, trans=[-size.x/2, -size.y/2, size.z/2]),
68 CR_corner([r,r,r], orient=ORIENT_ZNEG_180, trans=[-size.x/2, size.y/2, size.z/2]),
69 CR_corner([r,r,r], orient=ORIENT_ZNEG_270, trans=[ size.x/2, size.y/2, size.z/2])
70 ];
71 edges = [
72 CR_edge([r, r, s.x], orient=ORIENT_X, trans=[ 0, -h.y, -h.z]),
73 CR_edge([r, r, s.x], orient=ORIENT_X_90, trans=[ 0, h.y, -h.z]),
74 CR_edge([r, r, s.x], orient=ORIENT_X_180, trans=[ 0, h.y, h.z]),
75 CR_edge([r, r, s.x], orient=ORIENT_X_270, trans=[ 0, -h.y, h.z]),
76
77 CR_edge([r, r, s.y], orient=ORIENT_Y, trans=[ h.x, 0, -h.z]),
78 CR_edge([r, r, s.y], orient=ORIENT_Y_90, trans=[-h.x, 0, -h.z]),
79 CR_edge([r, r, s.y], orient=ORIENT_Y_180, trans=[-h.x, 0, h.z]),
80 CR_edge([r, r, s.y], orient=ORIENT_Y_270, trans=[ h.x, 0, h.z]),
81
82 CR_edge([r, r, s.z], orient=ORIENT_Z, trans=[-h.x, -h.y, 0]),
83 CR_edge([r, r, s.z], orient=ORIENT_Z_90, trans=[ h.x, -h.y, 0]),
84 CR_edge([r, r, s.z], orient=ORIENT_Z_180, trans=[ h.x, h.y, 0]),
85 CR_edge([r, r, s.z], orient=ORIENT_Z_270, trans=[-h.x, h.y, 0])
86 ];
87 faces = [
88 // Yes, these are degree 1 bezier patches. That means just the four corner points.
89 // Since these are flat, it doesn't matter what degree they are, and this will reduce calculation overhead.
90 bezier_patch_flat([s.y, s.z], N=1, orient=ORIENT_X, trans=[ h.x, 0, 0]),
91 bezier_patch_flat([s.y, s.z], N=1, orient=ORIENT_XNEG, trans=[-h.x, 0, 0]),
92
93 bezier_patch_flat([s.x, s.z], N=1, orient=ORIENT_Y, trans=[ 0, h.y, 0]),
94 bezier_patch_flat([s.x, s.z], N=1, orient=ORIENT_YNEG, trans=[ 0, -h.y, 0]),
95
96 bezier_patch_flat([s.x, s.y], N=1, orient=ORIENT_Z, trans=[ 0, 0, h.z]),
97 bezier_patch_flat([s.x, s.y], N=1, orient=ORIENT_ZNEG, trans=[ 0, 0, -h.z])
98 ];
99 // Generating all the patches above took about 0.05 secs.
100
101 if (cheat) {
102 // Hulling just the corners takes less than a second.
103 hull() bezier_polyhedron(tris=corners, splinesteps=splinesteps);
104 } else {
105 // Generating the polyhedron fully from bezier patches takes 3 seconds on my laptop.
106 bezier_polyhedron(patches=concat(edges, faces), tris=corners, splinesteps=splinesteps);
107 }
108}
109
110
111CR_cube(size=[100,100,100], r=20, splinesteps=9, cheat=false);
112cube(1);
113
114
115
116// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap